
// 请求配置接口
interface RequestConfig extends RequestInit {
  url: string
  baseURL?: string
  timeout?: number
}

// 响应数据接口
interface ApiResponse<T = any> {
  code: number
  message: string
  data: T
}

class HttpClient {
  private baseURL: string
  private timeout: number

  constructor(baseURL = '', timeout = 10000) {
    this.baseURL = baseURL
    this.timeout = timeout
  }

  // 获取token
  private getToken(): string | null {
    try {
      const userInfo = localStorage.getItem('userInfo')
      if (userInfo) {
        const parsed = JSON.parse(userInfo)
        // 检查token是否过期（如果有过期时间的话）
        if (parsed.tokenExpireTime) {
          if (new Date(parsed.tokenExpireTime) > new Date()) {
            return parsed.token
          } else {
            // token过期，清除本地存储
            localStorage.removeItem('userInfo')
            return null
          }
        } else if (parsed.token) {
          // 没有过期时间但有token，直接返回
          return parsed.token
        }
      }
    } catch (error) {
      console.error('获取token失败:', error)
      localStorage.removeItem('userInfo')
    }
    return null
  }

  // 请求拦截器
  private requestInterceptor(config: RequestConfig): RequestConfig {
    // 设置默认请求头
    const headers = new Headers(config.headers)
    
    // 如果不是FormData，设置默认Content-Type
    if (!headers.has('Content-Type') && !(config.body instanceof FormData)) {
      headers.set('Content-Type', 'application/json')
    }

    // 如果是FormData，删除Content-Type让浏览器自动设置
    if (config.body instanceof FormData && headers.has('Content-Type')) {
      headers.delete('Content-Type')
    }

    // 添加token
    const token = this.getToken()
    if (token) {
      headers.set('Authorization', `Bearer ${token}`)
    }

    return {
      ...config,
      headers
    }
  }

  // 响应拦截器
  private async responseInterceptor<T>(response: Response): Promise<ApiResponse<T>> {
    let result: any

    try {
      const contentType = response.headers.get('content-type')
      if (contentType && contentType.includes('application/json')) {
        result = await response.json()
      } else {
        result = await response.text()
      }
    } catch (error) {
      throw new Error('响应数据解析失败')
    }

    // 处理HTTP状态码错误
    if (!response.ok) {
      // 401 表示未授权，清除本地token
      if (response.status === 401) {
        localStorage.removeItem('userInfo')
        // 刷新页面或跳转到登录页
        if (window.location.pathname !== '/login') {
          window.location.href = '/login'
        }
      }
      
      const errorMessage = result?.message || `HTTP ${response.status}: ${response.statusText}`
      throw new Error(errorMessage)
    }

    // 处理业务错误码
    if (result.code !== undefined && result.code !== 200) {
      // 401 表示未授权，清除本地token
      if (result.code === 401) {
        localStorage.removeItem('userInfo')
        // 刷新页面或跳转到登录页
        if (window.location.pathname !== '/login') {
          window.location.href = '/login'
        }
      }
      throw new Error(result.message || '请求失败')
    }

    // 如果没有code字段，说明是直接返回的数据（如MyBatis Page对象）
    if (result.code === undefined) {
      return {
        code: 200,
        message: 'success',
        data: result
      }
    }

    return result
  }

  // 通用请求方法
  private async request<T>(config: RequestConfig): Promise<ApiResponse<T>> {
    // 应用请求拦截器
    const finalConfig = this.requestInterceptor(config)
    
    // 构建完整URL
    const url = finalConfig.baseURL || this.baseURL 
      ? `${finalConfig.baseURL || this.baseURL}${finalConfig.url}`
      : finalConfig.url

    // 创建AbortController用于超时控制
    const controller = new AbortController()
    const timeoutId = setTimeout(() => controller.abort(), finalConfig.timeout || this.timeout)

    try {
      const response = await fetch(url, {
        ...finalConfig,
        signal: controller.signal
      })

      clearTimeout(timeoutId)
      return await this.responseInterceptor<T>(response)
    } catch (error: any) {
      clearTimeout(timeoutId)
      
      if (error.name === 'AbortError') {
        throw new Error('请求超时')
      }
      
      throw error
    }
  }

  // GET请求
  async get<T>(url: string, config?: Omit<RequestConfig, 'url' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'GET'
    })
  }

  // POST请求
  async post<T>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'body'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'POST',
      body: data instanceof FormData ? data : (data ? JSON.stringify(data) : undefined)
    })
  }

  // PUT请求
  async put<T>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'body'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'PUT',
      body: data ? JSON.stringify(data) : undefined
    })
  }

  // DELETE请求
  async delete<T>(url: string, config?: Omit<RequestConfig, 'url' | 'method'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'DELETE'
    })
  }

  // PATCH请求
  async patch<T>(url: string, data?: any, config?: Omit<RequestConfig, 'url' | 'method' | 'body'>): Promise<ApiResponse<T>> {
    return this.request<T>({
      ...config,
      url,
      method: 'PATCH',
      body: data ? JSON.stringify(data) : undefined
    })
  }
}

// 创建默认实例
const http = new HttpClient('/api')

// 导出实例和类
export { HttpClient }
export default http